package com.whosly.demo.jmh.md;

import jdk.incubator.vector.LongVector;
import jdk.incubator.vector.VectorSpecies;

/**
 * 数组相加
 *
 * @author fengyang
 * @date 2023/7/2 下午9:35
 * @see <a href="fengyang@stoneatom.com">mailTo: fengyang@stoneatom.com</a>
 */
public class LongSumAction
{
    //定义SPECIES，表示Vector的类型
    private static final VectorSpecies<Long> SPECIES = LongVector.SPECIES_PREFERRED;
    private static int count = 5_000_000;

    private long[] longLeft = new long[count];
    private long[] longRight = new long[count];
    private long[] sumArr = new long[count];

    public LongSumAction() {
        init();
    }

    private void init() {
        for (Integer i = 0; i < count; i++) {
            longLeft[i] = i.longValue();
            longRight[i] = count - i.longValue();
        }
    }

    public void normalSum() {
        for (int i = 0; i < longLeft.length; i++) {
            sumArr[i] = longLeft[i] + longRight[i];
        }
    }

    public void vectorSum() {
        // 在Vector API中，每一个Vector代表一个寄存器，其可以存放若干个元素，取决于寄存器的大小和元素类型，
        // 例如当寄存器大小为128位时，可以存放4个int类型(每个int占32位)

        int i;
        int batchSize = longLeft.length;
        int end = SPECIES.loopBound(batchSize); //通过loopBound获取到对齐后的上限
        for (i = 0; i < end; i += SPECIES.length()) {
            //fromArray(SPECIES, longArr, i)表示从longArr的第i个位置元素开始取出SPECIES.length()个元素
            LongVector va = LongVector.fromArray(SPECIES, longLeft, i);
            LongVector vb = LongVector.fromArray(SPECIES, longRight, i);
            LongVector vc = va.add(vb); //调用add函数，使用SIMD指令求和
            //intoArray(longArr3, i)表示将vc寄存器中的内容存入longArr3中i偏移量开始的元素
            vc.intoArray(sumArr, i);
        }

        for(; i < batchSize; ++i) { //剩余的部分需要手动处理
            sumArr[i] = (longLeft[i] + longRight[i]);
        }
    }

    public static void main(String[] args)
    {
        LongSumAction longSum = new LongSumAction();

        longSum.vectorSum();
    }
}
